home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / deque.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  16.7 KB  |  529 lines

  1. #ifndef __DEQUE_CC
  2. #define __DEQUE_CC
  3. #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
  4.  
  5. /***************************************************************************
  6.  *
  7.  * deque.cc - Non-iniline definitions for the Standard Library deque class
  8.  *
  9.  * $Id: deque.cc,v 1.4 1996/08/28 18:41:29 smithey Exp $
  10.  *
  11.  ***************************************************************************
  12.  *
  13.  * Copyright (c) 1994
  14.  * Hewlett-Packard Company
  15.  *
  16.  * Permission to use, copy, modify, distribute and sell this software
  17.  * and its documentation for any purpose is hereby granted without fee,
  18.  * provided that the above copyright notice appear in all copies and
  19.  * that both that copyright notice and this permission notice appear
  20.  * in supporting documentation.  Hewlett-Packard Company makes no
  21.  * representations about the suitability of this software for any
  22.  * purpose.  It is provided "as is" without express or implied warranty.
  23.  *
  24.  *
  25.  ***************************************************************************
  26.  *
  27.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  28.  * ALL RIGHTS RESERVED *
  29.  * The software and information contained herein are proprietary to, and
  30.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  31.  * intends to preserve as trade secrets such software and information.
  32.  * This software is furnished pursuant to a written license agreement and
  33.  * may be used, copied, transmitted, and stored only in accordance with
  34.  * the terms of such license and with the inclusion of the above copyright
  35.  * notice.  This software and information or any other copies thereof may
  36.  * not be provided or otherwise made available to any other person.
  37.  *
  38.  * Notwithstanding any other lease or license that may pertain to, or
  39.  * accompany the delivery of, this computer software and information, the
  40.  * rights of the Government regarding its use, reproduction and disclosure
  41.  * are as set forth in Section 52.227-19 of the FARS Computer
  42.  * Software-Restricted Rights clause.
  43.  * 
  44.  * Use, duplication, or disclosure by the Government is subject to
  45.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  46.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  47.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  48.  * P.O. Box 2328, Corvallis, Oregon 97339.
  49.  *
  50.  * This computer software and information is distributed with "restricted
  51.  * rights."  Use, duplication or disclosure is subject to restrictions as
  52.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  53.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  54.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  55.  * then the "Alternate III" clause applies.
  56.  *
  57.  **************************************************************************/
  58.  
  59. #include <stdcomp.h>
  60.  
  61. #ifndef _RWSTD_NO_NAMESPACE
  62. namespace std {
  63. #endif
  64.  
  65.  
  66. template <class T, class Allocator>
  67. deque<T,Allocator>::~deque()
  68. {
  69.     while (!empty()) pop_front();
  70. }
  71.  
  72. template <class T, class Allocator>
  73. deque<T,Allocator>::size_type deque<T,Allocator>::buffer_size ()
  74. {
  75.   static size_type b_size = 
  76.       max((size_type)1,__RWSTD::__rw_allocation_size((value_type*)0,(size_type)0));
  77.   return b_size; 
  78. }
  79.  
  80. template <class T, class Allocator>
  81. void deque<T,Allocator>::allocate_at_begin ()
  82. {
  83.     pointer p = value_alloc_type(the_allocator).allocate(buffer_size(),start.current);
  84.     if (!empty())
  85.     {
  86.         if (start.node == map)
  87.         {
  88.             map_alloc_type ma(the_allocator);
  89.             difference_type i = finish.node - start.node;
  90.             size_type old_map_size = map_size;
  91.             map_size = (i + 1) * 2;
  92.             map_pointer tmp = ma.allocate(map_size,map);
  93.             copy(start.node, finish.node + 1, tmp + map_size / 4 + 1);
  94.             ma.deallocate(map,old_map_size);
  95.             map = tmp;
  96.             map[map_size / 4] = p;
  97.             start = iterator(p + buffer_size(), map + map_size / 4);
  98.             finish = iterator(finish.current, map + map_size / 4 + i + 1);
  99.         }
  100.         else
  101.         {
  102.             *--start.node = p;
  103.             start = iterator(p + buffer_size(), start.node);
  104.         }
  105.     }
  106.     else
  107.     {
  108.         map_size = buffer_size();
  109.         map = map_alloc_type(the_allocator).allocate(map_size,map);
  110.         map[map_size / 2] = p;
  111.         start = iterator(p + buffer_size() / 2 + 1, map + map_size / 2);
  112.         finish = start;
  113.     }
  114. }
  115.  
  116.  
  117. template <class T, class Allocator>
  118. void deque<T,Allocator>::allocate_at_end ()
  119. {
  120.     pointer p = value_alloc_type(the_allocator).allocate(buffer_size(),start.current);
  121.  
  122.     if (!empty())
  123.     {
  124.         if (finish.node == map + map_size - 1)
  125.         {
  126.             map_alloc_type ma(the_allocator);
  127.             difference_type i = finish.node - start.node;
  128.             size_type old_map_size = map_size;
  129.             map_size = (i + 1) * 2;
  130.             map_pointer tmp = map_alloc_type(the_allocator).allocate(map_size,map);
  131.             copy(start.node, finish.node + 1, tmp + map_size / 4);
  132.             map_alloc_type(the_allocator).deallocate(map,old_map_size);
  133.             map = tmp;
  134.             map[map_size / 4 + i + 1] = p;
  135.             start = iterator(start.current, map + map_size / 4);
  136.             finish = iterator(p, map + map_size / 4 + i + 1);
  137.         }
  138.         else
  139.         {
  140.             *++finish.node = p;
  141.             finish = iterator(p, finish.node);
  142.         }
  143.     }
  144.     else
  145.     {
  146.         map_size = buffer_size();
  147.         map = map_alloc_type(the_allocator).allocate(map_size,map);
  148.         map[map_size / 2] = p;
  149.         start = iterator(p + buffer_size() / 2, map + map_size / 2);
  150.         finish = start;
  151.     }
  152. }
  153.  
  154. template <class T, class Allocator>
  155. void deque<T,Allocator>::deallocate_at_begin ()
  156. {
  157.     value_alloc_type(the_allocator).deallocate(*start.node++,buffer_size());
  158.     if (empty())
  159.     {
  160.         start = iterator();
  161.         finish = start;
  162.         map_alloc_type(the_allocator).deallocate(map,map_size);
  163.     }
  164.     else
  165.         start = iterator(*start.node, start.node);
  166. }
  167.  
  168. template <class T, class Allocator>
  169. void deque<T,Allocator>::deallocate_at_end ()
  170. {
  171.     value_alloc_type(the_allocator).deallocate(*finish.node--,buffer_size());
  172.     if (empty())
  173.     {
  174.         start = iterator();
  175.         finish = start;
  176.         map_alloc_type(the_allocator).deallocate(map,map_size);
  177.     }
  178.     else
  179.         finish = iterator(*finish.node + buffer_size(), finish.node);
  180. }
  181.  
  182. template <class T, class Allocator>
  183. void deque<T,Allocator>::resize (size_type new_size)
  184. {
  185.     T value;
  186.     if (new_size > size())
  187.         insert(end(), new_size - size(), value);
  188.     else if (new_size < size())
  189.         erase(begin() + new_size,end());
  190. }
  191.  
  192. template <class T, class Allocator>
  193. void deque<T,Allocator>::resize (size_type new_size, T value)
  194. {
  195.     if (new_size > size())
  196.         insert(end(), new_size - size(), value);
  197.     else if (new_size < size())
  198.         erase(begin() + new_size,end());
  199. }
  200.  
  201. template <class T, class Allocator>
  202. _TYPENAME deque<T,Allocator>::iterator 
  203. deque<T,Allocator>::insert (deque<T,Allocator>::iterator position)
  204. {
  205.     T x;
  206.  
  207.     if (position == begin())
  208.     {
  209.         push_front(x); return begin();
  210.     }
  211.     else if (position == end())
  212.     {
  213.         push_back(x); return end() - 1;
  214.     }
  215.     else
  216.     {
  217.         difference_type index = position - begin();
  218.         if ((size_type)index < length)
  219.         {
  220.             push_front(*begin());
  221.             copy(begin() + 2, begin() + index + 1, begin() + 1);
  222.         }
  223.         else
  224.         {
  225.             push_back(*(end() - 1));
  226.             copy_backward(begin() + index, end() - 2, end() - 1);
  227.         }
  228.         *(begin() + index) = x;
  229.         return begin() + index;
  230.     }
  231. }
  232.  
  233. template <class T, class Allocator>
  234. _TYPENAME deque<T,Allocator>::iterator 
  235. deque<T,Allocator>::insert (deque<T,Allocator>::iterator position, const T& x)
  236. {
  237.     if (position == begin())
  238.     {
  239.         push_front(x); return begin();
  240.     }
  241.     else if (position == end())
  242.     {
  243.         push_back(x); return end() - 1;
  244.     }
  245.     else
  246.     {
  247.         difference_type index = position - begin();
  248.         if ((size_type)index < length)
  249.         {
  250.             push_front(*begin());
  251.             copy(begin() + 2, begin() + index + 1, begin() + 1);
  252.         }
  253.         else
  254.         {
  255.             push_back(*(end() - 1));
  256.             copy_backward(begin() + index, end() - 2, end() - 1);
  257.         }
  258.         *(begin() + index) = x;
  259.         return begin() + index;
  260.     }
  261. }
  262.  
  263. template <class T, class Allocator>
  264. void deque<T,Allocator>::insert_aux(deque<T,Allocator>::iterator position,      
  265.                                  size_type n, const T& x)
  266. {
  267.     difference_type index     = position - begin();
  268.     difference_type remainder = length   - index;
  269.  
  270.     if (remainder > index)
  271.     {
  272.         if (n > (size_type)index)
  273.         {
  274.             difference_type m = n - index;
  275.             while (m-- > 0) push_front(x);
  276.             difference_type i = index;
  277.             while (i--) push_front(*(begin() + n - 1));
  278. #ifdef _RWSTD_FILL_NAME_CLASH
  279.             std_fill(begin() + n, begin() + n + index, x);
  280. #else
  281.             fill(begin() + n, begin() + n + index, x);
  282. #endif
  283.         }
  284.         else
  285.         {
  286.             difference_type i = n;
  287.             while (i--) push_front(*(begin() + n - 1));
  288.             copy(begin() + n + n, begin() + n + index, begin() + n);
  289. #ifdef _RWSTD_FILL_NAME_CLASH
  290.             std_fill(begin() + index, begin() + n + index, x);
  291. #else
  292.             fill(begin() + index, begin() + n + index, x);
  293. #endif
  294.         }
  295.     }
  296.     else
  297.     {
  298.         difference_type orig_len = index + remainder;
  299.         if (n > (size_type)remainder)
  300.         {
  301.             difference_type m = n - remainder;
  302.             while (m-- > 0) push_back(x);
  303.             difference_type i = 0;
  304.             while (i < remainder) push_back(*(begin() + index + i++));
  305. #ifdef _RWSTD_FILL_NAME_CLASH
  306.             std_fill(begin() + index, begin() + orig_len, x);
  307. #else
  308.             fill(begin() + index, begin() + orig_len, x);
  309. #endif
  310.         }
  311.         else
  312.         {
  313.             difference_type i = 0;
  314.             while ((size_type)i < n) push_back(*(begin() + orig_len - n + i++));
  315.             copy_backward(begin() + index, begin() + orig_len - n,
  316.                           begin() + orig_len);
  317. #ifdef _RWSTD_FILL_NAME_CLASH
  318.             std_fill(begin() + index, begin() + index + n, x);
  319. #else
  320.             fill(begin() + index, begin() + index + n, x);
  321. #endif
  322.         }
  323.     }
  324. }
  325.  
  326.  
  327. #ifndef _RWSTD_NO_MEMBER_TEMPLATES
  328. template <class T, class Allocator>
  329. template <class InputIterator>
  330. void deque<T,Allocator>::insert (deque<T,Allocator>::iterator position, 
  331.                                  InputIterator first, InputIterator last)
  332. {
  333.     difference_type index     = position - begin();
  334.     difference_type remainder = length   - index;
  335.     size_type n;
  336.     __initialize(n, size_type(0));
  337.     distance(first, last, n);
  338.  
  339.     if (remainder > index)
  340.     {
  341.         if (n > index)
  342.         {
  343.             InputIterator m = last - index;
  344.             while (m != first) push_front(*--m);
  345.             difference_type i = index;
  346.             while (i--) push_front(*(begin() + n - 1));
  347.             copy(last - index, last, begin() + n);
  348.         }
  349.         else
  350.         {
  351.             difference_type i = n;
  352.             while (i--) push_front(*(begin() + n - 1));
  353.             copy(begin() + n + n, begin() + n + index, begin() + n);
  354.             copy(first, last, begin() + index);
  355.         }
  356.     }
  357.     else
  358.     {
  359.         difference_type orig_len = index + remainder;
  360.         if (n > remainder)
  361.         {
  362.             InputIterator m = first + remainder;
  363.             while (m != last) push_back(*m++);
  364.             difference_type i = 0;
  365.             while (i < remainder) push_back(*(begin() + index + i++));
  366.             copy(first, first + remainder, begin() + index);
  367.         }
  368.         else
  369.         {
  370.             difference_type i = 0;
  371.             while (i < n) push_back(*(begin() + orig_len - n + i++));
  372.             copy_backward(begin() + index, begin() + orig_len - n,
  373.                           begin() + orig_len);
  374.             copy(first, last, begin() + index);
  375.         }
  376.     }
  377. }
  378.  
  379. #else
  380.  
  381. template<class T, class Allocator>
  382. void deque<T,Allocator>::insert (deque<T,Allocator>::iterator position, 
  383.                                  deque<T,Allocator>::const_iterator first, 
  384.                                  deque<T,Allocator>::const_iterator last)
  385. {
  386.     difference_type index     = position - begin();
  387.     difference_type remainder = length   - index;
  388.     size_type n;
  389.     __initialize(n, size_type(0));
  390.     distance(first, last, n);
  391.  
  392.     if (remainder > index)
  393.     {
  394.         if (n > (size_type)index)
  395.         {
  396.             const_iterator m = last - index;
  397.             while (m != first) push_front(*--m);
  398.             difference_type i = index;
  399.             while (i--) push_front(*(begin() + n - 1));
  400.             copy(last - index, last, begin() + n);
  401.         }
  402.         else
  403.         {
  404.             difference_type i = n;
  405.             while (i--) push_front(*(begin() + n - 1));
  406.             copy(begin() + n + n, begin() + n + index, begin() + n);
  407.             copy(first, last, begin() + index);
  408.         }
  409.     }
  410.     else
  411.     {
  412.         difference_type orig_len = index + remainder;
  413.         if (n > (size_type)remainder)
  414.         {
  415.             const_iterator m = first + remainder;
  416.             while (m != last) push_back(*m++);
  417.             difference_type i = 0;
  418.             while (i < remainder) push_back(*(begin() + index + i++));
  419.             copy(first, first + remainder, begin() + index);
  420.         }
  421.         else
  422.         {
  423.             difference_type i = 0;
  424.             while ((size_type)i < n) push_back(*(begin() + orig_len - n + i++));
  425.             copy_backward(begin() + index, begin() + orig_len - n,
  426.                           begin() + orig_len);
  427.             copy(first, last, begin() + index);
  428.         }
  429.     }
  430. }
  431.  
  432. template<class T, class Allocator>
  433. void deque<T,Allocator>::insert (deque<T,Allocator>::iterator position, 
  434.                                  const T* first, const T* last)
  435. {
  436.     difference_type index     = position - begin();
  437.     difference_type remainder = length   - index;
  438.     size_type n;
  439.     __initialize(n, size_type(0));
  440.     distance(first, last, n);
  441.  
  442.     if (remainder > index)
  443.     {
  444.         if (n > (size_type)index)
  445.         {
  446.             const T* m = last - index;
  447.             while (m != first) push_front(*--m);
  448.             difference_type i = index;
  449.             while (i--) push_front(*(begin() + n - 1));
  450.             copy(last - index, last, begin() + n);
  451.         }
  452.         else
  453.         {
  454.             difference_type i = n;
  455.             while (i--) push_front(*(begin() + n - 1));
  456.             copy(begin() + n + n, begin() + n + index, begin() + n);
  457.             copy(first, last, begin() + index);
  458.         }
  459.     }
  460.     else
  461.     {
  462.         difference_type orig_len = index + remainder;
  463.         if (n > (size_type)remainder)
  464.         {
  465.             const T* m = first + remainder;
  466.             while (m != last) push_back(*m++);
  467.             difference_type i = 0;
  468.             while (i < remainder) push_back(*(begin() + index + i++));
  469.             copy(first, first + remainder, begin() + index);
  470.         }
  471.         else
  472.         {
  473.             difference_type i = 0;
  474.             while ((size_type)i < n) push_back(*(begin() + orig_len - n + i++));
  475.             copy_backward(begin() + index, begin() + orig_len - n,
  476.                           begin() + orig_len);
  477.             copy(first, last, begin() + index);
  478.         }
  479.     }
  480. }
  481.  
  482. #endif /*_RWSTD_NO_MEMBER_TEMPLATES*/
  483.  
  484. template <class T, class Allocator>
  485. _TYPENAME deque<T,Allocator>::iterator 
  486. deque<T,Allocator>::erase (deque<T,Allocator>::iterator position)
  487. {
  488.     if (end() - position > position - begin())
  489.     {
  490.         copy_backward(begin(), position, position + 1); 
  491.         pop_front();
  492.         return position + 1;
  493.     }
  494.     else
  495.     {
  496.         copy(position + 1, end(), position); 
  497.         pop_back();
  498.         return position;
  499.     }
  500. }
  501.     
  502. template <class T, class Allocator>
  503. _TYPENAME deque<T,Allocator>::iterator 
  504. deque<T,Allocator>::erase (deque<T,Allocator>::iterator first, 
  505.                            deque<T,Allocator>::iterator last)
  506. {
  507.     difference_type n = last - first;
  508.     if (end() - last > first - begin())
  509.     {
  510.         copy_backward(begin(), first, last);
  511.         while(n-- > 0) pop_front();
  512.         return last;
  513.     }
  514.     else
  515.     {
  516.         copy(last, end(), first);
  517.         while(n-- > 0) pop_back();
  518.         return first;
  519.     }
  520. }
  521.  
  522.  
  523.  
  524. #ifndef _RWSTD_NO_NAMESPACE
  525. }
  526. #endif
  527.  
  528. #pragma option pop
  529. #endif /* __DEQUE_CC */